/*
 * This file is part of org.kalmeo.util.
 * 
 * org.kalmeo.util is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * org.kalmeo.util is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with org.kalmeo.util.  If not, see <http://www.gnu.org/licenses/>.
 *  
 * Creation date : 21 nov. 07
 * Copyright (c) Kalmeo 2007-2008. All rights reserved.
 * http://www.kalmeo.org
 */

package org.kalmeo.util.worker;

import java.util.Vector;

/**
 * @author bbeaulant
 */
public class Worker implements Runnable {

	// The Worker static instance
	public static final Worker instance = new Worker();

	// The associated thread
	private Thread thread;

	// The worker run state
	private boolean running = false;
	
	// Frame duration (in ms)
	private int frameDuration = 60;

	// Task list
	private final Vector tasks = new Vector();
	
	/**
	 * @return <code>true</code> if the current Thread is the {@link Worker} thread
	 */
	public boolean isCurrentThread() {
		return (Thread.currentThread() == thread);
	}

	/**
	 * @return the running
	 */
	public boolean isRunning() {
		return running;
	}

	/**
	 * @return the frameDuration
	 */
	public int getFrameDuration() {
		return frameDuration;
	}

	/**
	 * @param frameDuration the frameDuration to set in milliseconds
	 */
	public void setFrameDuration(int frameDuration) {
		this.frameDuration = frameDuration;
	}

	/**
	 * Push a task to th worker task list.
	 * 
	 * @param task
	 */
	public void pushTask(WorkerTask task) {
		tasks.addElement(task);
	}

	/**
	 * Remove the first instance of a {@link WorkerTask} instance from task list
	 * 
	 * @param task
	 * @return <code>true</code> if the task is correctly removed
	 */
	public boolean removeTask(WorkerTask task) {
		return tasks.removeElement(task);
	}
	
	/**
	 * Remove all instances of {@link WorkerTask} from task list
	 */
	public void removeAllTasks() {
		tasks.removeAllElements();
	}

	/**
	 * Start the worker
	 */
	public void start() {
		if (!running) {
			running = true;
			thread = new Thread(this);
			thread.start();
		}
	}

	/**
	 * Stop the worker
	 */
	public void stop() {
		running = false;
	}

	/* (non-Javadoc)
	 * @see java.lang.Runnable#run()
	 */
	public void run() {
		while (running) {
			long startTime = System.currentTimeMillis();
			if (!tasks.isEmpty()) {
				synchronized (this) {
					for (int i = 0; i < tasks.size(); ++i) {
						WorkerTask task = (WorkerTask) tasks.elementAt(i);
						if (task.run()) {
							tasks.removeElementAt(i);
							i--;
						}
					}
				}
			}
			long executionTime = System.currentTimeMillis() - startTime;
			try {
				Thread.sleep(executionTime > frameDuration ? 1 : frameDuration - executionTime);
			} catch (InterruptedException e) {
			}
		}
		thread = null;
	}

}
